#include <locale.h>   
#include <wchar.h>   
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

typedef   enum {   
	BO_BIG_ENDIAN    =   0x02,
	BO_LITTLE_ENDIAN =   0x04,
}ENDIAN;

void PHEX(char *str, unsigned char *pOutputdata, int OutputSize)
{
	int     i   =   0;
	printf("%s   ->   ",   str,   OutputSize);
	printf("%d   bytes   :\n",   OutputSize); 
	
	for(i=0; i < OutputSize;   i++)
		printf("0x%02X   ",   *(pOutputdata   +   i));
	printf("\n\n"); 
}

static   const   BYTES_ORDER   =   BO_BIG_ENDIAN;
#define ZH_PRC ".936"   
#define ZH_TW ".950"   

#define   Print printf   
#define   MAX_SIZE_PER_UNICHAR 2
 
void reverse(char *array)
{
	char tmp = 0;
	
	tmp = array[0];
	array[0] = array[1];
	array[1] = tmp;
}

static int UC16S2GBS(const unsigned char *strin, int len, unsigned char *strout)
{
	char *temp   =   setlocale(LC_ALL,   ZH_PRC);
	char str_reorder[MAX_SIZE_PER_UNICHAR];
	int count   =   0;
	int rtncount   =   0;
	int leftbytes   =   len;
	
	assert(strin);
	assert(strout);

	while(   leftbytes   >   0   ) {
		strncpy(str_reorder,   strin,   MAX_SIZE_PER_UNICHAR);
		
		if   (BYTES_ORDER   ==   BO_BIG_ENDIAN) {
			reverse(str_reorder);   
		}

		strin   +=   MAX_SIZE_PER_UNICHAR;   
		leftbytes   -=   MAX_SIZE_PER_UNICHAR;   
		
		/* test   if   it   is   ASCII,     
		if   current   char   is   ASCII,   count   is   1   
		if   current   char   is   GB   or   Big5,   count   is   0   
		*/   
		count   =   wcstombs(strout,   (wchar_t*)str_reorder,   1);   
		if(count   ==   -1)   
		{   
			perror("UC16S2Local   error");   
			continue;   
		}   
		else   if(count   ==   0)   
		{   
			count   =   wcstombs(strout,   (wchar_t*)str_reorder,   MAX_SIZE_PER_UNICHAR);   
		}   
		
		if(count   ==   -1)   
		{   
			printf("Error!!!!\n");   
			continue;   
		}   
		else   if(count   ==   0)   
		{   
			break;   
		}   
		
		rtncount   +=   count;   
		strout   +=   count;   
	}   
	strout[rtncount]   =   '\0';   
	return   rtncount;   
}   

void   unicode_test(void)   
{   
	char *tmp   =   NULL;   
	unsigned   short     result   =   0;   
	unsigned   char str[]   =   {0x4e,0x5d,0x9e,0xde,0x62,0x32,0x52,0x87};   
	
	unsigned   char str_out[256];   
	int len   =   0;   
	
	if(BYTES_ORDER   ==   BO_BIG_ENDIAN) {   
		printf("use   BIG_ENDIAN\n");   
	} else {   
		printf("use   LITTLE_ENDIAN\n");   
	}
	
	/*UC16   to   GB*/
	memset(str_out,   0,   sizeof(str_out));
	len = UC16S2GBS(str,   100,   str_out);
	printf("convert   to   GB:   \nstring:   %s\n",   str_out);
	PHEX("hex",   str_out,   len);
}

void main(void)
{   
	unicode_test();   
}   
